/*
 * Copyright 2010-2012 Susanta Tewari. <freecode4susant@users.sourceforge.net>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package bd.org.apache.commons.math.stat.descriptive;

import bd.org.apache.commons.math.util.FastMath;
import bd.org.apache.commons.math.util.MathUtils;
import bd.org.apache.commons.math.util.Precision;

import java.io.Serializable;
import java.math.BigDecimal;

/**
 *  Value object representing the results of a univariate statistical summary.
 *
 * @version $Id: StatisticalSummaryValues.java 1244107 2012-02-14 16:17:55Z erans $
 */
public class StatisticalSummaryValues implements Serializable, StatisticalSummary {

    /** Serialization id */
    private static final long serialVersionUID = -5108854841843722536L;

    /** The sample mean */
    private final double mean;

    /** The sample variance */
    private final double variance;

    /** The number of observations in the sample */
    private final long n;

    /** The maximum value */
    private final double max;

    /** The minimum value */
    private final double min;

    /** The sum of the sample values */
    private final double sum;

    /**
     * Constructor
     *
     * @param mean  the sample mean
     * @param variance  the sample variance
     * @param n  the number of observations in the sample
     * @param max  the maximum value
     * @param min  the minimum value
     * @param sum  the sum of the values
     */
    public StatisticalSummaryValues(double mean, double variance, long n, double max, double min,
                                    double sum) {

        super();

        this.mean     = mean;
        this.variance = variance;
        this.n        = n;
        this.max      = max;
        this.min      = min;
        this.sum      = sum;
    }

    /**
     * @return Returns the max.
     */
    @Override
    public double getMax() {

        return max;
    }


    /**
     * @return Returns the mean.
     */
    @Override
    public BigDecimal getMean() {

        return new BigDecimal(mean);
    }


    /**
     * @return Returns the min.
     */
    @Override
    public double getMin() {

        return min;
    }


    /**
     * @return Returns the number of values.
     */
    @Override
    public long getN() {

        return n;
    }


    /**
     * @return Returns the sum.
     */
    @Override
    public double getSum() {

        return sum;
    }


    /**
     * @return Returns the standard deviation
     */
    @Override
    public BigDecimal getStandardDeviation() {

        return new BigDecimal(FastMath.sqrt(variance));
    }


    /**
     * @return Returns the variance.
     */
    @Override
    public double getVariance() {

        return variance;
    }


    /**
     * Returns true iff <code>object</code> is a
     * <code>StatisticalSummaryValues</code> instance and all statistics have
     *  the same values as this.
     *
     * @param object the object to test equality against.
     * @return true if object equals this
     */
    @Override
    public boolean equals(Object object) {

        if (object == this) {
            return true;
        }

        if (object instanceof StatisticalSummaryValues == false) {
            return false;
        }

        StatisticalSummaryValues stat = (StatisticalSummaryValues) object;

        return Precision.equalsIncludingNaN(stat.getMax(), getMax())
               && Precision.equalsIncludingNaN(stat.getMean().doubleValue(),
                   getMean().doubleValue()) && Precision.equalsIncludingNaN(stat.getMin(),
                       getMin()) && Precision.equalsIncludingNaN(stat.getN(), getN())
                                 && Precision.equalsIncludingNaN(stat.getSum(), getSum())
                                 && Precision.equalsIncludingNaN(stat.getVariance(), getVariance());
    }


    /**
     * Returns hash code based on values of statistics
     *
     * @return hash code
     */
    @Override
    public int hashCode() {

        int result = 31 + MathUtils.hash(getMax());

        result = result * 31 + MathUtils.hash(getMean().doubleValue());
        result = result * 31 + MathUtils.hash(getMin());
        result = result * 31 + MathUtils.hash(getN());
        result = result * 31 + MathUtils.hash(getSum());
        result = result * 31 + MathUtils.hash(getVariance());

        return result;
    }


    /**
     * Generates a text report displaying values of statistics.
     * Each statistic is displayed on a separate line.
     *
     * @return String with line feeds displaying statistics
     */
    @Override
    public String toString() {

        StringBuffer outBuffer = new StringBuffer();
        String       endl      = "\n";

        outBuffer.append("StatisticalSummaryValues:").append(endl);
        outBuffer.append("n: ").append(getN()).append(endl);
        outBuffer.append("min: ").append(getMin()).append(endl);
        outBuffer.append("max: ").append(getMax()).append(endl);
        outBuffer.append("mean: ").append(getMean()).append(endl);
        outBuffer.append("std dev: ").append(getStandardDeviation()).append(endl);
        outBuffer.append("variance: ").append(getVariance()).append(endl);
        outBuffer.append("sum: ").append(getSum()).append(endl);

        return outBuffer.toString();
    }
}
